<script lang="ts" setup>
import { ref, provide } from 'vue';
import { useRoute, useRouter, type RouteRecordRaw, type RouteMeta } from 'vue-router';
import { useAppStore } from '@/settings/stores';
import { listenerRouteChange } from '@/settings/utils/route-listener';
import { openWindow, regexUrl } from '@/settings/utils';
import useMenuTree from './use-menu-tree';
import OpenMenuItem from './item.vue';

defineOptions({
  name: 'OpenMenu',
});

const appStore = useAppStore();
const router = useRouter();
const route = useRoute();
const { menuTree } = useMenuTree();
// const collapsed = computed({
//   get() {
//     if (appStore.device === 'desktop') { return appStore.menuCollapse; }
//     return false;
//   },
//   set(value: boolean) {
//     appStore.menuCollapse = value;
//   },
// });

const openKeys = ref<string[]>([]);
const selectedKey = ref<string[]>([]);

const goto = (item: RouteRecordRaw) => {
  // Open external link
  if (regexUrl.test(item.path)) {
    openWindow(item.path);
    selectedKey.value = [item.meta?.__fullPath ?? '/'];
    return;
  }

  // Eliminate external link side effects
  const { hideInMenu, activeMenu } = item.meta as RouteMeta;
  if (route.path === item.path && !hideInMenu && !activeMenu) {
    selectedKey.value = [item.meta?.__fullPath ?? '/'];
    return;
  }

  // Trigger router change
  router.push({
    path: item.meta?.__fullPath ?? '/',
  });
};

const findMenuOpenKeys = (target: string) => {
  const result: string[] = [];
  let isFind = false;

  const backtrack = (item: RouteRecordRaw, keys: string[]) => {
    if (item.meta?.__fullPath === target || (item.meta?.hideChildrenInMenu && item.redirect === target)) {
      isFind = true;
      result.push(...keys);
      return;
    }
    if (item.children?.length) {
      item.children.forEach((el) => {
        backtrack(el, [...keys, el.meta?.__fullPath ?? '/']);
      });
    }
  };

  menuTree.value.forEach((el: RouteRecordRaw) => {
    // Performance optimization
    if (isFind) {
      return;
    }

    backtrack(el, [el.meta?.__fullPath ?? '/']);
  });

  return result;
};

listenerRouteChange((newRoute) => {
  const { notAuth, activeMenu, hideInMenu } = newRoute.meta;

  if (!notAuth && (!hideInMenu || activeMenu)) {
    const menuOpenKeys = findMenuOpenKeys(activeMenu || newRoute.fullPath);
    const keySet = new Set([...menuOpenKeys, ...openKeys.value]);

    openKeys.value = [...keySet];

    selectedKey.value = [
      activeMenu || menuOpenKeys[menuOpenKeys.length - 1],
    ];
  }
}, true);

const setCollapse = (val: boolean) => {
  if (appStore.device === 'desktop') {
    appStore.menuCollapse = val;
  }
};

provide('menuGoto', goto);
</script>

<template>
  <AMenu
    mode="vertical"
    :show-collapse-button="appStore.device !== 'mobile'"
    :selected-keys="selectedKey"
    auto-open
    class="open-menu h-full w-full"
    @collapse="setCollapse"
  >
    <OpenMenuItem :elements="menuTree" />
  </AMenu>
</template>

<style lang="scss" scoped>
.open-menu {
  :deep(.arco-menu-inner) {
    .arco-menu-inline-header {
      display: flex;
      align-items: center;
    }

    .arco-menu-indent-list {
      .arco-menu-indent:first-child {
        width: 15px;

        &:first-child {
          width: 34px;
        }
      }
    }

    .arco-icon {
      &:not(.arco-icon-down) {
        font-size: 18px;
      }
    }
  }
}
</style>
